import { httpClient, withRetry } from './http';
import {
  User,
  LoginRequest,
  LoginResponse,
  ApiResponse,
} from '../types';

export class AuthService {
  private static instance: AuthService;

  private constructor() {}

  public static getInstance(): AuthService {
    if (!AuthService.instance) {
      AuthService.instance = new AuthService();
    }
    return AuthService.instance;
  }

  /**
   * 用户登录
   */
  public async login(credentials: LoginRequest): Promise<LoginResponse> {
    try {
      const response = await httpClient.post<LoginResponse>('/auth/login', credentials);
      
      // 存储认证信息
      if (response.data?.token) {
        this.setAuthToken(response.data.token);
        this.setUserInfo(response.data.user);
      }

      return response;
    } catch (error) {
      console.error('Login failed:', error);
      throw error;
    }
  }

  /**
   * 用户登出
   */
  public async logout(): Promise<void> {
    try {
      await httpClient.post('/auth/logout');
    } catch (error) {
      console.error('Logout failed:', error);
    } finally {
      // 无论成功与否都清除本地存储
      this.clearAuthInfo();
    }
  }

  /**
   * 获取用户资料
   */
  public async getProfile(): Promise<ApiResponse<User>> {
    return withRetry(
      async () => httpClient.get<ApiResponse<User>>('/users/profile'),
      2,
      1000
    )();
  }

  /**
   * 刷新令牌
   */
  public async refreshToken(): Promise<string> {
    const response = await httpClient.post<ApiResponse<{ token: string }>>('/auth/refresh');
    if (response.data?.token) {
      this.setAuthToken(response.data.token);
      return response.data.token;
    }
    throw new Error('Failed to refresh token');
  }

  /**
   * 检查认证状态
   */
  public isAuthenticated(): boolean {
    const token = this.getAuthToken();
    const user = this.getUserInfo();
    
    if (!token || !user) {
      return false;
    }

    // 检查token是否过期（简单的base64解码检查）
    try {
      const payload = JSON.parse(atob(token.split('.')[1]));
      const currentTime = Math.floor(Date.now() / 1000);
      return payload.exp > currentTime;
    } catch {
      return false;
    }
  }

  /**
   * 检查用户权限
   */
  public hasRole(role: string): boolean {
    const user = this.getUserInfo();
    return user?.role === role;
  }

  /**
   * 检查是否为管理员
   */
  public isAdmin(): boolean {
    return this.hasRole('admin');
  }

  /**
   * 获取认证令牌
   */
  public getAuthToken(): string | null {
    return localStorage.getItem('auth_token');
  }

  /**
   * 设置认证令牌
   */
  public setAuthToken(token: string): void {
    localStorage.setItem('auth_token', token);
  }

  /**
   * 获取用户信息
   */
  public getUserInfo(): User | null {
    const userInfo = localStorage.getItem('user_info');
    if (userInfo) {
      try {
        return JSON.parse(userInfo);
      } catch {
        return null;
      }
    }
    return null;
  }

  /**
   * 设置用户信息
   */
  public setUserInfo(user: User): void {
    localStorage.setItem('user_info', JSON.stringify(user));
  }

  /**
   * 清除认证信息
   */
  public clearAuthInfo(): void {
    localStorage.removeItem('auth_token');
    localStorage.removeItem('user_info');
  }

  /**
   * 获取认证头
   */
  public getAuthHeader(): { Authorization: string } | {} {
    const token = this.getAuthToken();
    return token ? { Authorization: `Bearer ${token}` } : {};
  }

  /**
   * 自动刷新令牌
   */
  public startTokenRefresh(): void {
    // 每25分钟自动刷新一次令牌（假设令牌30分钟过期）
    setInterval(async () => {
      if (this.isAuthenticated()) {
        try {
          await this.refreshToken();
          console.log('Token refreshed successfully');
        } catch (error) {
          console.error('Failed to refresh token:', error);
          // 如果刷新失败，清除认证信息并跳转到登录页
          this.clearAuthInfo();
          window.location.href = '/login';
        }
      }
    }, 25 * 60 * 1000); // 25分钟
  }
}

// 导出单例实例
export const authService = AuthService.getInstance();

// 认证守卫函数
export const requireAuth = (redirectTo: string = '/login') => {
  if (!authService.isAuthenticated()) {
    window.location.href = redirectTo;
    return false;
  }
  return true;
};

// 权限守卫函数
export const requireRole = (role: string, redirectTo: string = '/unauthorized') => {
  if (!authService.hasRole(role)) {
    window.location.href = redirectTo;
    return false;
  }
  return true;
};

// 管理员守卫函数
export const requireAdmin = (redirectTo: string = '/unauthorized') => {
  return requireRole('admin', redirectTo);
};

export default authService;
